package com.yishoubao.demo.utils;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author YASSER
 * @version: 1.0.0
 * @description: 签名验证工具类
 * @modified: <文件修改说明>
 */
public class SignUtils {
    /**
     * 默认编码规则
     */
    private static final String CHARSET = "UTF-8";

    /**
     * 将订单金额格式化为2位小数的字符串
     * @param amount -- 订单金额，单位元，2位小数
     * @return
     */
    public static String formatAmount(double amount) {
        BigDecimal bigDecimal = new BigDecimal(String.valueOf(amount));
        return bigDecimal.setScale(2, BigDecimal.ROUND_DOWN).toString();
    }

    /**
     * 获取字符串的md5数据
     * @param str -- 原始数据
     * @return
     */
    public static String getMD5(String str) {
        String md5Str = DigestUtils.md5Hex(str);
        return md5Str;
    }

    /**
     * 获取md5的签名数据
     * 1、对请求参数(刨去sign、status、msg和value为空)根据参数名称的ASCII字典序排序
     * 2、将请求参数生成字符串 strA = "key1=value1&key2=value2&key3=value3";
     * 3、将请求参数生成的字符串拼接上秘钥(md5key)，md5Str = strA + "&key=md5Key";
     * 4、对拼接的md5Str字符串进行md5，获得签名
     * @param requestMap -- 请求参数集合
     * @param md5Key -- 商户秘钥
     * @return
     */
    public static String getSignOfMD5(Map<String, String> requestMap, String md5Key) {
        String[] keys = new String[requestMap.size()];
        requestMap.keySet().toArray(keys);
        Arrays.sort(keys);
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : keys) {
            if(Objects.equals("sign", key) || Objects.equals("status", key) || Objects.equals("msg", key) || Objects.equals("code", key)) {
                continue;
            }
            String value = requestMap.get(key);
            if(StringUtils.isBlank(value)) {
                continue;
            }
            stringBuilder.append(key);
            stringBuilder.append("=" + value);
            stringBuilder.append("&");
        }
        stringBuilder.append("key=" + md5Key);
        return getMD5(stringBuilder.toString()).toLowerCase();
    }

    /**
     * 检查签名是否正确
     * @param requestMap -- 请求数据
     * @param sign -- 签名
     * @param md5Key -- 签名
     * @return
     */
    public static boolean isRightSign(Map<String, String> requestMap, String sign, String md5Key) {
        String signStr = getSignOfMD5(requestMap, md5Key);
        return Objects.equals(sign, signStr);
    }

    public static void main(String[] args) {
        Map<String, String> requestMap = new HashMap<>(4);
        requestMap.put("merCode", MerchantConfig.MER_CODE);
        requestMap.put("merSubCode", "8001001");
        requestMap.put("orderNo", "1541495131401");
        String sign = SignUtils.getSignOfMD5(requestMap, MerchantConfig.MER_KEY);
        requestMap.put("sign", sign);
        System.out.println(requestMap);
    }

}
